package cn.monkey.data.mongo.ds.tenant;

import cn.monkey.data.entity.datascope.DatascopeDefinition;
import cn.monkey.data.entity.datascope.DatascopeType;
import cn.monkey.data.entity.dto.TenantQueryRequest;
import cn.monkey.data.mongo.ds.MongoBeforeSelectBehavior;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.util.CollectionUtils;

import java.util.Collection;

public class TenantBeforeSelectBehavior implements MongoBeforeSelectBehavior {

    static Criteria from(DatascopeDefinition dsDefinition) {
        String type = dsDefinition.getType();
        String rid = dsDefinition.getRid();
        Criteria criteria = null;
        if (DatascopeType.GROUP.getCode().equals(type)) {
            criteria = Criteria.where("groupId").is(rid);
        } else if (DatascopeType.PARTITION.getCode().equals(type)) {
            criteria = Criteria.where("partitionId").is(rid);
        } else if (DatascopeType.PERSONAL.getCode().equals(type)) {
            criteria = new Criteria().orOperator(Criteria.where("creator.k").is(rid),
                    Criteria.where("updater.k").is(rid));
        }
        Collection<DatascopeDefinition> and = dsDefinition.getAnd();
        if (!CollectionUtils.isEmpty(and)) {
            Criteria[] array = and.stream().map(TenantBeforeSelectBehavior::from).toArray(Criteria[]::new);
            criteria = criteria == null ? new Criteria().andOperator(array) : criteria.andOperator(array);
        }
        Collection<DatascopeDefinition> or = dsDefinition.getOr();
        if (!CollectionUtils.isEmpty(or)) {
            Criteria[] array = or.stream().map(TenantBeforeSelectBehavior::from).toArray(Criteria[]::new);
            criteria = criteria == null ? new Criteria().orOperator(array) : criteria.orOperator(array);
        }
        return criteria;
    }

    @Override
    public Criteria beforeSelect(TenantQueryRequest q) {
        DatascopeDefinition dsDefinition = q.getDsDefinition();
        if (dsDefinition == null) {
            return null;
        }
        return from(dsDefinition);
    }
}
